/*链表实现多项式加法和乘法
 *输入格式：
 * 项数 系数1 指数1 系数2 指数2 ...
 */
#include<stdio.h>
#include<stdlib.h>

typedef struct PolyNode* Polynomial;
typedef struct PolyNode
{
	int coef;//系数
	int expon;//指数
	Polynomial next;
}PolyNode;


void insertNewNode(int c,int e, PolyNode* & pRear)//注意这里要用引用，虽然pRear的类型PolyNode*本身为指针，但传入的也是指针，这里若去掉引用相当于在对一个指针类型的形参操作，而不是实参
{
	PolyNode* p;
	p = (PolyNode *)malloc(sizeof(PolyNode));
	p->coef = c;
	p->expon = e;
	p->next = NULL;
	pRear->next = p;
	pRear = p;//记得更新尾指针
}

void insertMidNode(int c, int e, PolyNode*& pRear)
{
	PolyNode* p;
	p = (PolyNode*)malloc(sizeof(PolyNode));
	p->coef = c;
	p->expon = e;
	p->next = pRear->next;
	pRear->next = p;
}

Polynomial readPoly()
{
	Polynomial poly,rear;
	int c, e, N;
	printf("共几项？\n");
	scanf("%d", &N);
	printf("请输入每项\n");
	poly = (Polynomial)malloc(sizeof(PolyNode));
	poly->next = NULL;
	rear = poly;
	for (; N > 0; N--)
	{
		scanf("%d %d", &c, &e);
		insertNewNode(c, e, rear);
	}
	//释放头结点
	Polynomial t = poly;
	poly = poly->next;
	free(t);

	return poly;
}

Polynomial polyAdd(Polynomial p1,Polynomial p2)
{
	Polynomial resPoly, rear;
	resPoly = (Polynomial)malloc(sizeof(PolyNode));
	resPoly->next = NULL;
	rear = resPoly;
	while (p1 != NULL && p2 != NULL)
	{
		if (p1->expon == p2->expon)
		{
			insertNewNode(p1->coef + p2->coef, p1->expon, rear);
			p1 = p1->next;
			p2 = p2->next;
		}
		else if (p1->expon > p2->expon)
		{
			insertNewNode(p1->coef, p1->expon, rear);
			p1 = p1->next;
		}
		else if(p1->expon < p2->expon)
		{
			insertNewNode(p2->coef, p2->expon, rear);
			p2 = p2->next;
		}
	}
	for (; p1 != NULL; p1 = p1->next)
		insertNewNode(p1->coef, p1->expon, rear);
	for (; p2 != NULL; p2 = p2->next)
		insertNewNode(p2->coef, p2->expon, rear);
	Polynomial t = resPoly;
	resPoly = resPoly->next;
	free(t);
	return resPoly;
}

Polynomial polyMult(Polynomial p1,Polynomial p2)
{
	Polynomial multp,mRear;
	Polynomial p2t = p2;
	multp = (Polynomial)malloc(sizeof(PolyNode));
	multp->next = NULL;
	mRear = multp;
	
	while (p2t != NULL)
	{//先用二式×一式第一项，生成初始multp
		insertNewNode(p1->coef * p2t->coef, p1->expon + p2t->expon, mRear);
		p2t = p2t->next;
	}

	p1 = p1->next;

	while (p1 != NULL)
	{
		p2t = p2;
		mRear = multp;//multp是头结点指针,下一个才存数据,由于后面 <e 时需要，这里保留头结点
		while (p2t != NULL)//p1嵌套p2,每项之间都相乘
		{
			int e = p1->expon + p2t->expon;
			while (mRear->next != NULL && mRear->next->expon>e)//每有一新项就遍历乘积多项式，找到插入位置
			{
				mRear = mRear->next;
			}
			if (mRear->next != NULL && mRear->next->expon == e)
			{
				mRear->next->coef += (p1->coef * p2t->coef);//已有此次数的多项式，直接系数累加
			}
			//else
			//{
			//	Polynomial t = (Polynomial)malloc(sizeof(PolyNode));
			//	t->coef = p1->coef * p2t->coef;
			//	t->expon = p1->expon + p2t->expon;
			//	t->next = mRear->next;
			//	mRear->next = t;
			//	mRear = t;//更新尾指针
			//}
			else if (mRear->next != NULL && mRear->next->expon < e)//
			{
				insertMidNode(p1->coef * p2t->coef, p1->expon + p2t->expon, mRear);//插入中间
			}
			else
			{
				insertNewNode(p1->coef * p2t->coef, p1->expon + p2t->expon, mRear);
			}

			p2t = p2t->next;
		}
		p1 = p1->next;
	}
	//释放头结点
	Polynomial t = multp;
	multp = multp->next;
	free(t);
	return multp;
}


void printPoly(Polynomial p)
{
	while (p!=NULL)
	{
		printf("%d ,%d\n", p->coef, p->expon);
		p = p->next;
	}
}

int main()
{
	Polynomial p1,p2,addp;
	p1 = readPoly();
	p2 = readPoly();
	addp = polyAdd(p1, p2);
	printf("---加法结果---\n");
	printPoly(addp);
	Polynomial multp;
	multp = polyMult(p1, p2);
	printf("---乘法结果---\n");
	printPoly(multp);

	return 0;
}